﻿using System;
using System.Web.Services;
using System.Xml;
using System.Collections;


namespace SZJT.Framework.Services
{
    public abstract class BaseCommunicate:WebService
    {
        protected XmlDocument XmlDoc = new XmlDocument();
        private static readonly object Lock = new object();
        private static Hashtable _suPool;
        private static Hashtable _stPool;

        private static bool CheckUid(string uid, string sid)
        {
            CheckPool(uid);
            if (null == _suPool)
                return false;
            if (_suPool.ContainsKey(uid))
            {
                if (_suPool[uid].ToString().Equals(sid))
                    return true;
                return false;
            }
            return false;
        }
        private static void PushsuPool(string uid, string sid)
        {
            if (null == _suPool)
            {
                lock (Lock)
                {
                    if (null == _suPool)
                        _suPool = new Hashtable();
                }
            }
            if (_suPool.ContainsKey(uid))
            {
                lock (Lock)
                {
                    if (_suPool.ContainsKey(uid))
                        _suPool.Remove(uid);
                }
            }
            else
            {
                lock (Lock)
                {
                    _suPool[uid] = sid;
                    PushstPool(uid);
                }
            }
        }
        private static void PushstPool(string uid)
        {
            if (null == _stPool)
                _stPool = new Hashtable();
            if (_stPool.ContainsKey(uid))
                _stPool.Remove(uid);
            _stPool.Add(uid, System.DateTime.Now);
        }
        private static void CheckPool(string uid)
        {
            if (null == _stPool)
                return;
            try
            {
                if (_stPool.ContainsKey(uid))
                {
                    if (System.Convert.ToDateTime(_stPool[uid]).AddSeconds(60 * int.Parse(System.Configuration.ConfigurationManager.AppSettings["ActiveTimeout"])) < System.DateTime.Now)
                    {
                        lock (Lock)
                        {
                            _stPool.Remove(uid);
                            _suPool.Remove(uid);
                        }
                    }
                }
            }
            catch
            {
                //?????
                return;
            }
        }
        private static void UpdateOperaterTime(string uid)
        {
            CheckPool(uid);
            if (_stPool.ContainsKey(uid))
            {
                lock (Lock)
                {
                    _stPool[uid] = System.DateTime.Now;
                }
            }
        }
        private static string GetGuid()
        {
            return System.Guid.NewGuid().ToString();
        }

        private const bool checkUserInfo = false;
        private const bool checkPermisssion = false;

        protected abstract string GetCustomData(string userId, string taskGuid, string dataGuid, string dataType);
        protected abstract int SetCustomData(string userId, string taskGuid, string dataGuid, string dataType, string xmlData);
        protected abstract string TransformCustomData(string userId, string taskGuid, string xmlTransform);
        
        [WebMethod(EnableSession = true)]
        public virtual string GetData(string userId, string taskGuid, string dataGuid, string dataType)
        {
            //if (DataType.Equals("NewGuid") && TaskGuid.Equals("e32cc6ac-199c-4a6f-93f8-937d3e482d13") && DataGuid.Equals("e32cc6ac-199c-4a6f-93f8-937d3e482d13"))
            //    return GetGuid();
            //if (DataType.Equals("AppTaskList"))
            //    return Plugin.GetAppTaskList(UserID, TaskGuid, DataGuid, DataType);
            //if (DataType.Equals("ServerInfo"))
            //    return ServerInfoService.GetData(TaskGuid, DataGuid, DataType);
            //if (!CheckUid(UserID, Session.SessionID))
            //    return string.Empty;
            //if (!PermissionManager.GetPermission(TaskGuid).HasPermission(UserID, TaskGuid, DataType, ActionType.R))
            //    return string.Empty;
            //UpdateOperaterTime(UserID);
            //return AdapterFactory.GetAdapter(TaskGuid).GetData(TaskGuid, DataGuid, DataType).InnerXml;
            switch (dataType)
            {
                case "NewGuid": return GetGuid();
                case "AppTaskList": return Plugin.GetAppTaskList(userId, taskGuid, dataGuid, dataType);
                case "ServerInfo": return ServerInfoService.GetData(taskGuid, dataGuid, dataType);
                default:
                    var result = GetCustomData(userId, taskGuid, dataGuid, dataType);
                    return string.IsNullOrEmpty(result) ? Adapter.AdapterFactory.GetAdapter(taskGuid).GetData(taskGuid, dataGuid, dataType).InnerXml : result;
            }
        }

        [WebMethod(EnableSession = true)]
        public virtual int SetData(string userId, string taskGuid, string dataGuid, string dataType, string xmlData)
        {
            if (!string.IsNullOrEmpty(xmlData))
                XmlDoc.LoadXml(xmlData);
            //if (CheckUid(UserID, Session.SessionID))
            //    return -3;
            //if (PermissionManager.GetPermission(TaskGuid).HasPermission(UserID, TaskGuid, DataType, ActionType.D) ||
            //PermissionManager.GetPermission(TaskGuid).HasPermission(UserID, TaskGuid, DataType, ActionType.C))
            //{
            //UpdateOperaterTime(UserID);
            var result = SetCustomData(userId, taskGuid, dataGuid, dataType, xmlData);
            return result==2012 ? Adapter.AdapterFactory.GetAdapter(taskGuid).SetData(taskGuid, dataGuid, dataType, XmlDoc.DocumentElement) : result;
            //}
            //return -3;
        }

        [WebMethod(EnableSession = true)]
        public virtual string TransformData(string userId, string taskGuid, string xmlTransform)
        {
            try
            {
                var transformMessage = Framework.Core.XmlTransformMessage.Parse(xmlTransform);
                if (!string.IsNullOrEmpty(xmlTransform))
                    XmlDoc.LoadXml(xmlTransform);
                if (transformMessage.DataType.Equals("PageTicket"))
                {
                    var verifyNode = transformMessage.GetElement("VerifyCode");
                    var verifyCode = verifyNode.Value;
                    //if (null == Session[Session.SessionID])
                    //    return string.Empty;
                    //if (!Session[Session.SessionID].ToString().Equals(verifyCode))
                    //    return string.Empty;
                    //Session.Remove(Session.SessionID);
                    var resultNode = Adapter.AdapterFactory.GetAdapter(taskGuid).TransformData(taskGuid, XmlDoc);
                    //var uid = resultNode.SelectSingleNode("//UserID").InnerXml;
                    //PushsuPool(uid, Session.SessionID);
                    return resultNode.InnerXml;
                }
                if (transformMessage.DataType.Equals("LoginTicket") || transformMessage.DataType.Equals("CertTicket"))
                    return AccountService.TransformData(userId, taskGuid, transformMessage);
                //if (CheckUid(UserID, Session.SessionID))
                //    return string.Empty;
                //if (!PermissionManager.GetPermission(TaskGuid).HasPermission(UserID, TaskGuid, transformMessage.DataType, ActionType.R))
                //    return string.Empty;
                //UpdateOperaterTime(UserID);
                var result = TransformCustomData(userId, taskGuid, xmlTransform);
                return string.IsNullOrEmpty(result) ? Adapter.AdapterFactory.GetAdapter(taskGuid).TransformData(taskGuid, XmlDoc).InnerXml : result;
            }
            catch(Exception e)
            {
                LoggerHelper.WriteCodePointInfo(e.Message + "错误！");
                return string.Empty;
            }
        }
    }
}
